﻿using Elastic.Clients.Elasticsearch;
using FlyingEye.Common;
using FlyingEye.MixingProcess;
using System;
using System.Threading;
using System.Threading.Tasks;

namespace FlyingEye.Repositories
{
    public class MixingControlCentreDeleteException : Exception
    {
        public DeleteByQueryResponse IndexResponse { get; }

        public MixingControlCentreDeleteException(DeleteByQueryResponse response)
        {
            IndexResponse = response;
        }
    }

    public class MixingControlCentreInsertException : Exception
    {
        public IndexResponse IndexResponse { get; }

        public MixingControlCentreInsertException(IndexResponse response)
        {
            IndexResponse = response;
        }
    }

    public class MixingControlCentreUpdateException : Exception
    {
        public UpdateResponse<MixingControlCentrelModel> IndexResponse { get; }

        public MixingControlCentreUpdateException(UpdateResponse<MixingControlCentrelModel> response)
        {
            IndexResponse = response;
        }
    }

    internal class MixingControlCentreRepository : IMixingControlCentreRepository
    {
        private const string MixingProcessIndex = "MixingControlCentrel";

        private readonly ElasticsearchClient _es;

        public MixingControlCentreRepository(ESClient esClient)
        {
            _es = esClient;
        }

        public async Task DeleteAsync(string id, CancellationToken cancellationToken = default)
        {
            // 构建删除请求，删除匹配条件下的数据
            var response = await _es.DeleteByQueryAsync<MixingControlCentrelModel>(MixingProcessIndex,
                descriptor => descriptor.Query(q => q.Term(new Elastic.Clients.Elasticsearch.QueryDsl.TermQuery("Id")
                {
                    Value = id,
                })));

            if (response.IsValidResponse)
            {
                throw new MixingControlCentreDeleteException(response);
            }
        }

        public async Task InsertAsync(MixingControlCentrelModel entity, bool autoSave = false, CancellationToken cancellationToken = default)
        {
            var response = await _es.IndexAsync(entity, MixingProcessIndex);

            if (!response.IsValidResponse)
            {
                throw new MixingControlCentreInsertException(response);
            }
        }

        public async Task UpdateAsync(MixingControlCentrelModel entity, bool autoSave = false, CancellationToken cancellationToken = default)
        {
            UpdateResponse<MixingControlCentrelModel> response = await _es.UpdateAsync<MixingControlCentrelModel, MixingControlCentrelModel>(MixingProcessIndex, 1, u => u
                                    .Doc(entity));

            if (response.IsValidResponse)
            {
                throw new MixingControlCentreUpdateException(response);
            }
        }
    }
}
